package org.xserver.disruptor.producer;

import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.xserver.component.core.XServerHttpContextAttachment;
import org.xserver.component.core.XServerHttpResponse;
import org.xserver.component.core.interfaces.InterfaceContext;
import org.xserver.component.core.interfaces.InterfaceMeta;
import org.xserver.component.exception.ResouceNotFoundError;
import org.xserver.component.prototype.annotation.ReturnType;
import org.xserver.component.prototype.annotation.ReturnTypeEnum;
import org.xserver.component.prototype.processor.ReturnTypeProcessor;
import org.xserver.disruptor.annotation.EventConsumer;

import com.lmax.disruptor.EventHandler;

@EventConsumer
@Service
public class MessageEventConsumer implements EventHandler<RequestEvent>{
	private final static Logger logger = LoggerFactory.getLogger(MessageEventConsumer.class);
	@Resource
	private InterfaceContext interfaceContext;
	@Override
	public void onEvent(RequestEvent event, long sequence, boolean endOfBatch)
			throws Exception {
		if(event.getAttachment()==null){
			logger.error("event is null");
		}else{
			Object result = wrapResponse(event.getAttachment(),event.getMethod().invoke(event.getHttpInterface(),event.getParameters()));
			event.getWriteHandler().writeResponse(event.getAttachment(),result);
		}
		
	}
	protected Object wrapResponse(XServerHttpContextAttachment attachment,
			Object result) throws Exception {
		String path = attachment.getRequest().getPath();
		InterfaceMeta interfaceMeta = interfaceContext.getInterfaceMeta(path);
		if (interfaceMeta == null) {
			throw new ResouceNotFoundError(HttpResponseStatus.BAD_REQUEST,
					"PATH \'" + path + "\' CANNOT MATCH ANY INTERFACE.");
		}

		Method method = interfaceMeta.getMethod();

		/**
		 * first do with returnType, it means business return result type
		 */
		ReturnType returnType = method.getAnnotation(ReturnType.class);
		return doReturnType(attachment, returnType, result);
	}
	private Object doReturnType(XServerHttpContextAttachment attachment,
			ReturnType returnType, Object result) {
		if (returnType != null) {
			String value = returnType.value();
			ReturnTypeEnum returnTypeEnum = ReturnTypeEnum.valueOf(value
					.toUpperCase());
			ReturnTypeProcessor processor = returnTypeEnum.getProcessor();
			if (processor != null) {
				XServerHttpResponse response = attachment.getResponse();
				response.setContentTypeHeader(returnTypeEnum.getContentType()
						+ "; " + XServerHttpResponse.DEFAULT_CHARSET);
				result = processor.returnProcess(result);
			}
		}

		return result;
	}
}
